package com.hk.webapp.utils;

import com.hk.webapp.res_config.FileUploadConfig;
import com.hk.webapp.res_config.OssConfig;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypes;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.UUID;

@Slf4j
public class FileUploadUtils {

    public static String getFileType(String fileSuffix) {
        String fileType;
        switch (fileSuffix) {
            case "jpg":
            case "jpeg":
            case "gif":
            case "png":
            case "bmp":
            case "icon":
                fileType = "images";
                break;
            case "doc":
            case "docx":
            case "zip":
            case "rar":
            case "ppt":
            case "xls":
            case "xlsx":
            case "txt":
                fileType = "file";
                break;
            case "mp4":
            case "avi":
            case "flv":
            case "swf":
            case "3gp":
            case "wmv":
                fileType = "video";
                break;
            case "mp3":
            case "wav":
                fileType = "music";
                break;
            default:
                fileType = "others";
        }
        return fileType;
    }

    @SuppressWarnings("ALL")
    public static String uploadFileByOss(OssConfig ossConfig, FileUploadConfig fileUploadConfig, MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String fileExtensionName = FilenameUtils.getExtension(originalFilename);
        String fileType = FileUploadUtils.getFileType(Strings.nullToEmpty(fileExtensionName));
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String sysDate = df.format(LocalDateTime.now());
        String path = fileUploadConfig.getPath().replace(fileUploadConfig.getFileTypePlaceHolder(), fileType).replace(fileUploadConfig.getDatePlaceHolder(), sysDate);
        OSSClient client = null;
        try {
            InputStream is = file.getInputStream();
            //文件名
            String fileName = file.getName();
            //文件大小
            long fileSize = file.getSize();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(is.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(file.getContentType());
            //指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            path = StringUtil.buildString(path, UUID.randomUUID().toString().replace("-", ""), ".", fileExtensionName);
            client = new OSSClient(ossConfig.getEndPoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
            PutObjectResult result = client.putObject(ossConfig.getBucket(), path, file.getInputStream(), metadata);
            String requestId = result.getRequestId();
            if (StringUtils.isNotBlank(requestId)) {
                return StringUtil.buildString(ossConfig.getDomainName(), path);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (!Objects.isNull(client)) {
                client.shutdown();
            }
        }
        return StringUtils.EMPTY;
    }

    @SuppressWarnings("ALL")
    public static String uploadFileByOss(OssConfig ossConfig, FileUploadConfig fileUploadConfig, String urlStr) {
        OSSClient client = null;
        try {
            //new一个URL对象
            URL url = new URL(urlStr);
            //打开链接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            connection.setRequestMethod("GET");
            //超时响应时间为5秒
            connection.setConnectTimeout(5 * 1000);

            //通过输入流获取图片数据
            InputStream fileStream = connection.getInputStream();

            MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
            MimeType mimeType = allTypes.forName(connection.getContentType());
            String ext = mimeType.getExtension();

            String fileType = FileUploadUtils.getFileType(Strings.nullToEmpty(ext.replace(".", "")));
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
            String sysDate = df.format(LocalDateTime.now());
            String path = fileUploadConfig.getPath().replace(fileUploadConfig.getFileTypePlaceHolder(), fileType).replace(fileUploadConfig.getDatePlaceHolder(), sysDate);


            //文件名
            String fileName = UUID.randomUUID().toString().replace("-", "");
            //文件大小
            long fileSize = connection.getContentLength();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(fileSize);
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(connection.getContentType());
            //指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            path = StringUtil.buildString(path, fileName, ext);
            client = new OSSClient(ossConfig.getEndPoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
            PutObjectResult result = client.putObject(ossConfig.getBucket(), path, fileStream, metadata);
            String requestId = result.getRequestId();
            if (StringUtils.isNotBlank(requestId)) {
                return StringUtil.buildString(ossConfig.getDomainName(), path);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (!Objects.isNull(client)) {
                client.shutdown();
            }
        }
        return StringUtils.EMPTY;
    }

    @SuppressWarnings("ALL")
    public static String uploadFileByLocal(FileUploadConfig fileUploadConfig, MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String fileExtensionName = FilenameUtils.getExtension(originalFilename);
        String fileType = FileUploadUtils.getFileType(Strings.nullToEmpty(fileExtensionName));
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String sysDate = df.format(LocalDateTime.now());
        String path = fileUploadConfig.getPath().replace(fileUploadConfig.getFileTypePlaceHolder(), fileType).replace(fileUploadConfig.getDatePlaceHolder(), sysDate);
        path = StringUtil.buildString(File.separator, path);
        //上传文件   (上传文件流的形式)
        path = StringUtil.buildString(path, UUID.randomUUID().toString().replace("-", ""), ".", fileExtensionName);
        File tempFile = new File(StringUtil.buildString(fileUploadConfig.getRootPath(),path));
        try {
            FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
        } catch (Exception e) {
            e.printStackTrace();
            return StringUtils.EMPTY;
        }
        return StringUtil.buildString(fileUploadConfig.getDomain(),path.replace("\\", "/"));
    }
}
